package com.blb.aop.util;

import com.blb.aop.service.impl.StudentServiceImpl;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.time.LocalDateTime;

/**
 * 日志切面类
 */
@Aspect
@Component
public class LogAspect {

    //获得日志输出对象
    private Logger logger = Logger.getLogger(LogAspect.class);

    /**
     * 定义切面
     */
    @Pointcut("@annotation(com.blb.aop.util.MyLog)")
    public void pointcut(){
    }

    /**
     * 异常处理
     * @param joinPoint
     */
    @AfterThrowing(pointcut = "pointcut()",throwing = "throwable")
    public void afterThrowingLog(JoinPoint joinPoint,Throwable throwable){
        logger.error(joinPoint.getSignature().getName() + "方法出现了异常:" + throwable.getMessage(),throwable);
    }

    /**
     * 方法环绕处理
     * @param joinPoint
     */
    @Around("pointcut()")
    public Object aroundLog(ProceedingJoinPoint joinPoint){
        try {
            String name = joinPoint.getSignature().getName();
            long start = System.currentTimeMillis();
            //获得方法上的注解
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            MyLog annotation = method.getAnnotation(MyLog.class);
            System.out.println(annotation.value());

            logger.debug(name + "方法开始执行" + LocalDateTime.now());
            //获得方法的参数
            logger.debug("方法的参数："+joinPoint.getArgs());
            //执行原始方法
            Object result = joinPoint.proceed();
            logger.debug("方法的返回值：" + result);
            long end = System.currentTimeMillis();
            logger.debug("方法执行结束，耗时：" + (end - start));
            return result;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return null;
    }

    /**
     * 前置处理
     */
//    @Before("pointcut()")
//    public void beforeLog(JoinPoint joinPoint){
//        System.out.println("这是前置通知，开始执行方法：" + joinPoint.getSignature().getName());
//    }

    /**
     * 后置处理
     * @param joinPoint
     */
//    @After("pointcut()")
//    public void afterLog(JoinPoint joinPoint){
//        System.out.println("这是后置通知，执行方法结束：" + joinPoint.getSignature().getName());
//    }

    /**
     * 方法返回处理
     * @param joinPoint
     */
//    @AfterReturning("pointcut()")
//    public void afterReturningLog(JoinPoint joinPoint){
//        System.out.println("这是方法返回，执行方法返回：" + joinPoint.getSignature().getName());
//    }
}
